home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 August: Tool Chest / Dev.CD Aug 00 TC Disk 2.toast / pc / sample code / overview / dtscpluslibrary / sources / fileclass.cp < prev    next >
Encoding:
Text File  |  2000-06-23  |  11.8 KB  |  490 lines

  1. /*
  2.     File:        FileClass.cp
  3.  
  4.     Contains:    TFile is a simple object that does file manipulations    
  5.                   TFile.cp contains the TFile class and subclass member functions.
  6.  
  7.     Written by: Kent Sandvik    
  8.  
  9.     Copyright:    Copyright © 1992-1999 by Apple Computer, Inc., All Rights Reserved.
  10.  
  11.                 You may incorporate this Apple sample source code into your program(s) without
  12.                 restriction. This Apple sample source code has been provided "AS IS" and the
  13.                 responsibility for its operation is yours. You are not permitted to redistribute
  14.                 this Apple sample source code as "Apple sample source code" after having made
  15.                 changes. If you're going to re-distribute the source, we require that you make
  16.                 it clear in the source that the code was descended from Apple sample source
  17.                 code, but that you've made changes.
  18.  
  19.     Change History (most recent first):
  20.                 8/18/1999    Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
  21.                 
  22.  
  23. */
  24. #ifndef _FILECLASS_
  25. #include "FileClass.h"
  26. #endif
  27.  
  28.  
  29. // _________________________________________________________________________________________________________ //
  30. //    TFile
  31. #pragma segment File
  32. TFile::TFile(char* name)
  33. // Create a file object based on the name.
  34. {
  35.     this->Initialize();                            // initialize internal fields to known values
  36.  
  37.     // We are going to assume a lot of things for the default setting
  38.     // and files, for instance that we are creating files in the current working directory (folder)
  39.  
  40.     WDPBRec folderBlock;
  41.     folderBlock.ioNamePtr = nil;
  42.     fError = ::PBHGetVolSync(&folderBlock);
  43.     VASSERT(fError == noErr, ("Problems with PBHGetVol = %d", fError));
  44.  
  45.     fFileSpec.vRefNum = folderBlock.ioVRefNum;
  46.     fFileSpec.parID = folderBlock.ioWDDirID;
  47.     c2p(name);
  48.     Pstrcpy(fFileSpec.name, (StringPtr)name);
  49. }
  50.  
  51.  
  52. #pragma segment File
  53. TFile::TFile(FSSpec theSpec)
  54. // Create a file object based on the FSSpec.
  55. {
  56.     this->Initialize();                            // initialize internal fields to known values
  57.  
  58.     fFileSpec.vRefNum = theSpec.vRefNum;        // store the FSSpec
  59.     fFileSpec.parID = theSpec.parID;
  60.     Pstrcpy(fFileSpec.name, theSpec.name);
  61. }
  62.  
  63.  
  64. #pragma segment File
  65. TFile::TFile(short volume,
  66.              long dirID,
  67.              Str63 name)
  68. // Create a file object based on the volume no, directory ID and the name.
  69. {
  70.     this->Initialize();                            // initialize internal fields to known values
  71.  
  72.     fFileSpec.vRefNum = volume;                    // store values into the FSSpec
  73.     fFileSpec.parID = dirID;
  74.     Pstrcpy(fFileSpec.name, name);
  75. }
  76.  
  77.  
  78. #pragma segment File
  79. TFile::~TFile()
  80. // Default destructor -- empty for the time being.
  81. {
  82. }
  83.  
  84.  
  85. #pragma segment File
  86. void TFile::Initialize()
  87. // Initialize fields to known values.
  88. {
  89.     fFileType = kDefaultType;                    // gee, we assume everyone's reading/writing text files
  90.     fCreator = kDefaultCreator;                    // and who's that?
  91.     fOpened = false;                            // not open yet…
  92.     fFlushing = false;                            // assume things are OK, so we don't flush unless something's critical
  93. }
  94.  
  95.  
  96. // MAIN INTERFACE
  97. #pragma segment File
  98. Boolean TFile::Create()
  99. // Create a new file.
  100. {
  101.     if (!this->FileExists())
  102.     {
  103.         fError = ::HCreate(fFileSpec.vRefNum, fFileSpec.parID, fFileSpec.name, fCreator, fFileType);
  104.         VASSERT(fError == noErr, ("Problems with HCreate = %d\n", fError));
  105.         goto CreateOK;
  106.     }
  107.     return false;
  108. CreateOK:return true;
  109. }
  110.  
  111.  
  112. #pragma segment File
  113. Boolean TFile::Rename(char* newName)
  114. // Rename the file.
  115. {
  116.     if (this->FileExists())
  117.     {
  118.         c2p(newName);
  119.         fError = ::HRename(fFileSpec.vRefNum, fFileSpec.parID, fFileSpec.name, (StringPtr)newName);
  120.         VASSERT(fError == noErr, ("Problems with HRename = %d", fError));
  121.  
  122.         Pstrcpy(fFileSpec.name, (StringPtr)newName);
  123.         goto RenameOK;
  124.     }
  125.     return false;
  126. RenameOK:return true;
  127. }
  128.  
  129.  
  130. #pragma segment File
  131. void TFile::Delete()
  132. // Delete the file.
  133. {
  134.     if (fOpened)
  135.         this->Close();                            // first close the file
  136.  
  137.     fError = ::HDelete(fFileSpec.vRefNum, fFileSpec.parID, fFileSpec.name);
  138.     VASSERT(fError == noErr, ("nProblems with HDelete = %d", fError));
  139. }
  140.  
  141.  
  142. #pragma segment File
  143. Boolean TFile::FileExists()
  144. // Test if the file exists or not.
  145. {
  146.     FInfo info;
  147.     fError = HGetFInfo(fFileSpec.vRefNum, fFileSpec.parID, fFileSpec.name, &info);
  148.     return (fError == noErr);
  149. }
  150.  
  151.  
  152. // ACCESSORS AND MUTATORS
  153. #pragma segment File
  154. void TFile::SetType(const OSType creator,
  155.                     const OSType fileType)
  156. // Set file type.
  157. {
  158.     fCreator = creator;
  159.     fFileType = fileType;
  160. }
  161.  
  162.  
  163. #pragma segment File
  164. void TFile::SetFileName(const Str63 fileName)
  165. // Set file name.
  166. {
  167.     Pstrcpy(fFileSpec.name, (StringPtr)fileName);
  168. }
  169.  
  170.  
  171. #pragma segment File
  172. FInfo TFile::GetFileInfo()
  173. // Get FInfo from the specified file.
  174. {
  175.     FInfo info;
  176.     fError = ::HGetFInfo(fFileSpec.vRefNum, fFileSpec.parID, fFileSpec.name, &info);
  177.     VASSERT(fError == noErr, ("Problems with HGetFInfo = %d", fError));
  178.     return info;
  179. }
  180.  
  181.  
  182. // _________________________________________________________________________________________________________ //
  183. //    TDataFile
  184.  
  185. // CONSTRUCTORS AND DESTRUCTORS
  186. #pragma segment File
  187. TDataFile::TDataFile(char* name) :
  188.     TFile(name)
  189. // Default constructor, create a file based on the name.
  190. {
  191. }
  192.  
  193. #pragma segment File
  194. TDataFile::~TDataFile()
  195. // Default destructor -- empty for the time being.
  196. {
  197. }
  198.  
  199.  
  200. // MAIN INTERFACE
  201. #pragma segment File
  202. Boolean TDataFile::Open(SignedByte permission)
  203. // Open a file for data fork only access.
  204. {
  205.     fError = ::HOpen(fFileSpec.vRefNum, fFileSpec.parID, fFileSpec.name, permission, &fRefNum);
  206.     VASSERT(fError == noErr, ("Problems with HOpen = %d", fError));
  207.  
  208.     if (fError == noErr)
  209.         fOpened = true;
  210.     return (fError == noErr);
  211. }
  212.  
  213.  
  214. #pragma segment File
  215. Boolean TDataFile::Close()
  216. // Close the file.
  217. {
  218.     fError = ::FSClose(fRefNum);
  219.     VASSERT(fError == noErr, ("Problems with FSClose = %d", fError));
  220.  
  221.     if (fError == noErr)
  222.         fOpened = false;
  223.  
  224.     if (fFlushing)                                // if flagged, flush the volume
  225.     {
  226.         fError = ::FlushVol(NULL, fFileSpec.vRefNum);
  227.         VASSERT(fError == noErr, ("Problems with FlushVol = %d", fError));
  228.     }
  229.  
  230.     return (fError == noErr);
  231. }
  232.  
  233.  
  234. #pragma segment File
  235. Boolean TDataFile::WriteHandle(Handle h)
  236. // Write a handle to file (the whole handle).
  237. {
  238.     long len = ::GetHandleSize(h);                // get lenght of handle
  239.  
  240.     fError = ::SetFPos(fRefNum, fsFromStart, kNoOffset);// move pointer to beginning of file
  241.     VASSERT(fError == noErr, ("Problems with SetFPos = %d", fError));
  242.  
  243.     fError = ::FSWrite(fRefNum, &len, *h);        // write the handle to disk
  244.     VASSERT(fError == noErr, ("Problems with FSWrite = %d", fError));
  245.  
  246.     fError = ::SetEOF(fRefNum, len);            // change size of file if needed
  247.     VASSERT(fError == noErr, ("Problems with SetEOF = %d", fError));
  248.  
  249.     if (fFlushing)
  250.     {
  251.         fError = ::FlushVol(NULL, fFileSpec.vRefNum);
  252.         VASSERT(fError == noErr, ("Problems with FlushVol = %d", fError));
  253.     }
  254.     return (fError == noErr);
  255. }
  256.  
  257.  
  258. #pragma segment File
  259. Handle TDataFile::ReadHandle()
  260. // Read handle from the file (the whole handle).
  261. {
  262.     Handle h = NULL;
  263.     long len;
  264.  
  265.     fError = ::GetEOF(fRefNum, &len);            // get size of handle in file
  266.     VASSERT(fError == noErr, ("Problems with GetEOF = %d", fError));
  267.  
  268.     h = ::NewHandle(len);                        // create a new handle
  269.     if (h == NULL)                                // problems creating a handle 
  270.     {
  271.         ASSERT(fError == noErr, "\pProblems with NewHandle");
  272.         goto ReadHandleFalse;
  273.     }
  274.  
  275.     fError = ::SetFPos(fRefNum, fsFromStart, kNoOffset);
  276.     VASSERT(fError == noErr, ("Problems with SetFPos = %d", fError));
  277.  
  278.     fError = ::FSRead(fRefNum, &len, *h);        // read into handle
  279.     VASSERT(fError == noErr, ("Problems with SetFPos = %d", fError));
  280.  
  281.     return h;
  282. ReadHandleFalse:return NULL;
  283. }
  284.  
  285.  
  286. #pragma segment File
  287. Boolean TDataFile::Write(Ptr buffer,
  288.                          long bytes)
  289. // Write N bytes from buffer to file.
  290. {
  291.     fError = ::FSWrite(fRefNum, &bytes, buffer);
  292.     VASSERT(fError == noErr, ("Problems with FSWrite = %d", fError));
  293.     return (fError == noErr);
  294. }
  295.  
  296.  
  297. #pragma segment File
  298. Boolean TDataFile::Read(Ptr buffer,
  299.                         long bytes)
  300. // Read N bytes from file to buffer.
  301. {
  302.     fError = ::FSRead(fRefNum, &bytes, buffer);
  303.     VASSERT(fError == noErr, ("Problems with FSWrite = %d", fError));
  304.     return (fError == noErr);
  305. }
  306.  
  307.  
  308. #pragma segment File
  309. Boolean TDataFile::SetMark(short from,
  310.                            long offset)
  311. // Set file mark (beginning, end, offset).
  312. {
  313.     if (fOpened)                                // have an open file?
  314.     {
  315.         fError = ::SetFPos(fRefNum, from, offset);
  316.         VASSERT(fError == noErr, ("Problems with SetFPos = %d", fError));
  317.         goto SetMarkOK;
  318.     }
  319.     else
  320.         return false;
  321. SetMarkOK:return (fError == noErr);
  322. }
  323.  
  324.  
  325. #pragma segment File
  326. long TDataFile::GetMark()
  327. // Get file mark (offset).
  328. {
  329.     long offset = 0;
  330.  
  331.     fError = ::GetFPos(fRefNum, &offset);
  332.     VASSERT(fError == noErr, ("Problems with GetFPos = %d", fError));
  333.  
  334.     return offset;
  335. }
  336.  
  337.  
  338. #pragma segment File
  339. Boolean TDataFile::Reset()
  340. // Set file mark to beginning of file.
  341. {
  342.     return (this->SetMark(fsFromStart, kNoOffset));// set mark to beginning of file
  343. }
  344.  
  345.  
  346. #pragma segment File
  347. Boolean TDataFile::GotoEndOfFile()
  348. // Set file mark to end of file.
  349. {
  350.     return (this->SetMark(fsFromLEOF, kNoOffset));// set mark to end of file
  351. }
  352.  
  353.  
  354. // _________________________________________________________________________________________________________ //
  355. //    TResourceFile
  356. // CONSTRUCTORS AND DESTRUCTORS
  357. #pragma segment File
  358. TResourceFile::TResourceFile(char* name) :
  359.     TFile(name)
  360. // Default destructor, create a TResourceFile object.
  361. {
  362. }
  363.  
  364.  
  365. #pragma segment File
  366. TResourceFile::~TResourceFile()
  367. // Default destructor -- not used for the time being.
  368. {
  369. }
  370.  
  371.  
  372. // MAIN INTERFACE
  373. #pragma segment File
  374. Boolean TResourceFile::Create()
  375. // Create the actual resource file.
  376. {
  377.     if (!this->FileExists())
  378.     {
  379.         Boolean result = TFile::Create();        // call inherited create
  380.         if (result)                                // if OK
  381.         {
  382.             ::HCreateResFile(fFileSpec.vRefNum, fFileSpec.parID, fFileSpec.name);
  383.             goto CreateResourceOK;
  384.         }
  385.         else
  386.             goto CreateResourceFalse;            // result = false
  387.     }
  388.     else
  389.         goto CreateResourceFalse;                // couldn't create a file that exists
  390.  
  391. CreateResourceFalse:return false;
  392. CreateResourceOK:if (ResError() == noErr)
  393.         return true;
  394.     else
  395.         return false;
  396. }
  397.  
  398.  
  399. #pragma segment File
  400. Boolean TResourceFile::Open(SignedByte permission)
  401. // Open the resource file.
  402. {
  403.     if (fOpened)
  404.     {
  405.         fRefNum = ::HOpenResFile(fFileSpec.vRefNum, fFileSpec.parID, fFileSpec.name, permission);
  406.         VASSERT(fRefNum != -1, ("Problems with HOpenResFile = %d", ::ResError()));
  407.         if (::ResError() == 0)
  408.             goto ResourceFileOpenOK;
  409.         else
  410.             goto ResourceFileOpenFalse;
  411.     }
  412.     else
  413.         goto ResourceFileOpenFalse;                // can't open an already open file
  414. ResourceFileOpenFalse:return false;
  415. ResourceFileOpenOK:fOpened = true;
  416.     return true;
  417. }
  418.  
  419.  
  420. #pragma segment File
  421. Boolean TResourceFile::Close()
  422. // Close the resource file.
  423. {
  424.     if (fOpened)
  425.     {
  426.         ::CloseResFile(fRefNum);
  427.         VASSERT(fRefNum != -1, ("Problems with CloseResFile = %d", ::ResError()));
  428.         if (::ResError() == 0)
  429.             goto ResourceFileCloseOK;
  430.         else
  431.             goto ResourceFileCloseFalse;
  432.     }
  433. ResourceFileCloseFalse:return false;
  434. ResourceFileCloseOK:fRefNum = 0;
  435.     fOpened = false;
  436.     return true;
  437. }
  438.  
  439.  
  440. #pragma segment File
  441. Boolean TResourceFile::HasResourceFork()
  442. // Check if the supposed resource file actually has a resource fork.
  443. {
  444.     HFileParam pb;
  445.  
  446.     pb.ioNamePtr = fFileSpec.name;                // get the name
  447.     pb.ioVRefNum = fFileSpec.vRefNum;            // and the volume
  448.     pb.ioDirID = fFileSpec.parID;                // and the DirID
  449.     pb.ioFDirIndex = 0;                            // zero this one
  450.  
  451.     fError = ::PBHGetFInfoSync((HParmBlkPtr) & pb);// call the right trap
  452.     VASSERT(fError == noErr, ("Problems with PBHGetFInfo = %d", fError));
  453.  
  454.     return (pb.ioFlRLgLen != 0);                // if the resource fork is non-zero, then we got one
  455. }
  456.  
  457.  
  458. #pragma segment File
  459. void TResourceFile::Update()
  460. // Update the resource file.
  461. {
  462.     if (fOpened)
  463.     {
  464.         ::UpdateResFile(fRefNum);
  465.         VASSERT(::ResError() == noErr, ("Problems with UpdateResFile = %d", ::ResError()));
  466.         if (fFlushing)
  467.         {
  468.             fError = ::FlushVol(NULL, fFileSpec.vRefNum);
  469.             VASSERT(fError == noErr, ("Problems with FlushVol = %d", fError));
  470.         }
  471.     }
  472. }
  473.  
  474.  
  475. #pragma segment File
  476. void TResourceFile::Assign()
  477. // Make sure that we are using this specified resource file.
  478. {
  479.     if (fOpened)
  480.         ::UseResFile(fRefNum);
  481. }
  482.  
  483.  
  484. // _________________________________________________________________________________________________________ //
  485. /*    Change History (most recent last):
  486.   No        Init.    Date        Comment
  487.   1            khs        12/27/92    New file
  488.   2            khs        1/14/93        Cleanup
  489. */
  490.